/*
 * @Author: xiaosihan 
 * @Date: 2024-05-25 05:18:49 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-05-25 16:08:55
 */

import { flatten, get, isNumber } from "lodash";
import { Box3, BufferAttribute, BufferGeometry, Group, Line, LineBasicMaterial, Mesh, MeshBasicMaterial, Shape, ShapeGeometry, Vector3 } from "three";
import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils";
import { degToRad } from "three/src/math/MathUtils";

type Coords = number[] | Coords[];

type Geojson = {
    type: string,
    features: Array<{
        type: string,
        properties: {
            id?: string,
            adcode?: any,
            size?: string,
            name?: string,
            cp?: [number, number],
            childNum?: 9
        },
        geometry: {
            type: string, // 'Point' | 'MultiPoint' | 'LineString' | 'MultiLineString' | 'Polygon' | 'MultiPolygon',
            coordinates: Coords
        }
    }>
}

// 地图轮廓线
export default class GeojsonLine extends Group {

    constructor(geojson: Geojson) {
        super();
        this.init(geojson);
    }

    size = new Vector3(1, 1, 1);

    init(geojson: Geojson) {

        geojson.features.map((f, index) => {
            const { adcode: code = "unkonw", name = "unkonw" } = f.properties;
            let points = f.geometry.coordinates as number[][][];
            if (!isNumber(get(points, [0, 0, 0]))) {
                //@ts-ignore
                points = flatten(points);
            }

            for (let i = 0; i < points.length; i++) {

                const positions = [];
                for (let ii = 0; ii < points[i].length; ii++) {
                    const [x, y] = points[i][ii];
                    positions.push(x, 0, y);
                }
                const geometry = new BufferGeometry();
                let positionArray = new Float32Array(positions);
                let position = new BufferAttribute(positionArray, 3, false);
                geometry.setAttribute("position", position);

                geometry.rotateX(degToRad(180));

                const line = new Line(geometry, new LineBasicMaterial({}));
                line.userData = { name, code };
                line.uuid = code;
                line.name = name;
                this.add(line);
            }

            const box3 = new Box3();
            const center = new Vector3();
            box3.setFromObject(this);
            box3.getSize(this.size);
            box3.getCenter(center);
        });

    }

}


